Distributed computing systems may have software components such as software objects or other kinds of individually addressable isolated entities, such as distributed objects, agents, actors and so forth. In general, each such component is individually addressable and has an unique identity, such as an integer, GUID, string or an opaque data structure in one or more implementations).
Typically application code transfers a component's state between server memory and the persistent store, as needed, or such transfer can be automatically performed by the executing runtime system on behalf of the component. One of the common programmability problems in distributed systems is that for most resources, such as a user account, a document, and so forth, an associated component (i.e., object) needs to be explicitly instantiated. The instantiation process usually includes a step of checking if the component exists in memory on one of the servers, and (in many cases) creating the component if it does not already exist; (the actual semantics of the component lookup operation instead of “find” is “find or create”).
In a distributed system, this instantiation/creation inherently leads to races when multiple processes check for the existence of an component, and when not found, try to create the component in parallel. A similar race condition issue relates to the deletion of components from memory, particularly when deletion is overlapped with one or more attempts to create the same component. The complexity of such possible situations leads to complex code that needs to handle checks for existence and creation, as well as to handle failures of duplicate creation attempts and inconsistency between the expected and actual state of the component at different points in time.